#第7章 函数
#函数别名
fun = abs;
print(fun(-123))

#! /usr/bin/python3
# -*- coding:UTF-8 -*-
#函数定义
def hello():
    print('hello world')

hello()

def doNoting():
    pass
doNoting()

# 必须参数
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
def parmsone(str):
    print(str)

parmsone('I\'m a param')

#关键字参数
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
def parmssome(name,age):
    print('名字是：',name)
    print('年龄是：',age)

print('必须参数，按照顺序传入')
parmssome('小明',21)

print('关键字参数，按照顺序传入')
parmssome('小明',21)

print('关键字参数，不按照顺序传入')
parmssome(age=21,name='小明')

#默认参数
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
def defaultParam(name,age=23):
    print('名称是：',name)
    print('年龄是：',age)

print('默认参数')
defaultParam('小明')

print('-------------------可变参数-------------------------------')
#可变参数
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
def changeParams(*abc123):
    print('---------打印可变参数start---------')
    for s in abc123:
        print('不定长参数',s)
    print('---------打印可变参数end-----------')

changeParams('小明','小张','小宇')
changeParams('小明','小张')
changeParams('小明')

print('-------------------组合参数-------------------------------')
#组合参数
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
def exp(p1,p2,p3=0,*p4,**p5):
    #*后可变参数为元组，**后可变参数为字典
    print('p1',p1,'p2',p2,'p3',p3,'p4',p4,'p5',p5)

exp(1,2)
exp(1,2,3)
exp(1,2,p3=3)
exp(1,2,3,'a','b')
exp(1,2,3,'a','b',x=3,y=4,z=5)

print('-------------------组合参数2-------------------------------')
def exp(*p1,**p2):
    print('p1',p1,'p2',p2)

tuple1=tuple([1,2,3,'a','b'])
print(tuple1)
dict1=dict([('小明',23),('小张',21),('小宇',22)])
print(dict1)
exp(*tuple1,**dict1)

print('-------------------局部变量-------------------------------')
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
x=50
def f(x):
    x=2
    print('局部变量x的值是：',x)

f(x)
print('全局变量x的值是：',x)


print('-------------------全局变量-------------------------------')
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
x=50
def f():
    global x
    x=2
    print('局部变量x的值是：',x)

f()
print('全局变量x的值是：',x)

print('-------------------返回函数和闭包-------------------------------')
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
def calc_sum(*args):
    x1=0
    for n in args:
        x1+=n
    return x1

print(calc_sum(1, 2, 3, 4, 5))

print('-------------------返回函数和闭包2-------------------------------')
def sum_late(*args):
    def cal_sum1():
        x2 = 0
        for n in args:
            x2 += n
        return x2

    return cal_sum1

print('sum_late()函数的结果是：', sum_late(1, 2, 3, 4, 5))
calSum = sum_late(1, 2, 3, 4, 5)
print('calc_sum()函数的结果是：',calSum())

fun1=sum_late(1,2,3,4,5)
fun2=sum_late(1,2,3,4,5)
print('fun1==fun2',fun1==fun2)


print('-------------------返回函数和闭包3-------------------------------')
def count():
    fs=[]
    for i in range(1,4):
        def f1():
            return i*i

        fs.append(f1)
    return fs

y1,y2,y3=count()
print(y1())

print('-------------------返回函数和闭包4-------------------------------')
# 以下注释代码报错：ValueError: not enough values to unpack (expected 3, got 1)
# def count():
#     def f4(j):
#         def g():
#             return j*j
#         return g
#     fs=[]
#     for i in range(1,4):
#         fs.append(f4(i))
#         return fs
#
# z1,z2,z3=count()
# print('f1的结果是：',z1())
# print('f2的结果是：',z2())
# print('f3的结果是：',z3())

print('-------------------递归函数-------------------------------')
def fact(n):
    if n==1:
        return 1
    return n * fact(n - 1)

print(fact(5))
#print(fact(1000))#栈堆溢出

print('-------------------尾递归优化-------------------------------')
def fact1(n):
    return fact_iter(n,1)

def fact_iter(num,product):
    if num==1:
        return product
    return fact_iter(num-1,num*product)

#print(fact1(1000))#仍然会报错，栈堆溢出，因为python不支持尾递归

print('-------------------filter()函数-------------------------------')
#过滤出列表中的所有奇数：
def is_odd(x5):
    return x5%2 ==1

newlist = filter(is_odd,[1,2,3,4,5,6,7,8,9,10])
print(list(newlist))

#把一个序列中的空字符串删掉
def not_empty(x6):
    return x6.strip()

newlist2 = filter(not_empty,['A ','B ','C ','D ','E ','F '])
print(list(newlist2))

print('-------------------匿名函数1-------------------------------')
#用函数表达
def funcxy(x,y):
    return x+y


print('函数计算的结果是：',funcxy(1,2))

#用lambda表达式表达，上面的函数等价于
c=lambda x,y:x+y
print('lambda表达式计算的结果是：',c(1,2))

print('-------------------匿名函数2-------------------------------')
#用函数表达
def funcabc(x):
    return x>3

newlist3 = list(filter(funcabc,[1,2,3,4,5]))
print('函数计算的结果是：',newlist3)

#lambda表达式与filter()函数结合
print('lambda表达式计算的结果是：',list(filter(lambda x:x>3,[1,2,3,4,5])))

c=lambda x,y=2,z=3:x+y+z
print(c(1))

print('-------------------偏函数-------------------------------')
#! /usr/bin/python3
# -*- coding:UTF-8 -*-
from functools import partial
def mod(x,y):
    return x%y


mod_100=partial(mod,100)
mod_1=partial(mod)
print('调用偏函数调用的结果是：',mod_100(7))
print('调用偏函数2调用的结果是：',mod_1(100,7))
print('调用自定义函数调用的结果是：',mod(100,7))

print('-------------------习题：快速排序-----------------------')
print('----------------quick sort1--------------------')
# ! /usr/bin/python3
# -*- coding:UTF-8 -*-
def quicksort(L):
  qsort(L, 0, len(L) - 1)

def qsort(L, first, last):
  if first < last:
    split = partition(L, first, last)
    qsort(L, first, split - 1)
    qsort(L, split + 1, last)

def partition(L, first, last):
  # 选取列表中的第一个元素作为划分元素
  pivot = L[first]
  leftmark = first + 1
  rightmark = last
  while True:
    while L[leftmark] <= pivot:
     # 如果列表中存在与划分元素pivot相等的元素，让它位于left部分
     # 以下检测用于划分元素pivot是列表中的最大元素时
     # 防止leftmark越界
      if leftmark == rightmark:
        break
      leftmark += 1
    while L[rightmark] > pivot:
      # 这里不需要检测，划分元素pivot是列表中的最小元素时
      # rightmark自动停在first处
      rightmark -= 1
    if leftmark < rightmark:
      # 此时，leftmark处的元素大于pivot
      # rightmark处的元素小于等于pivot，交换两者
      L[leftmark], L[rightmark] = L[rightmark], L[leftmark]
    else:
      break
  # 交换first处的划分元素与rightmark处的元素
  L[first], L[rightmark] = L[rightmark], L[first]
  # 返回划分元素pivot的最终位置
  return rightmark
#函数调用示例：
num_list = [5, -4, 6, 3, 7, 11, 1, 2]
print('排序之前: ' + str(num_list))
quicksort(num_list)
print('排序之后: ' + str(num_list))

print('----------------quick sort2-----------------------')
def quickSort(L, low, high):
    i = low
    j = high
    if i >= j:
        return L
    key = L[i]
    while i < j:
        while i < j and L[j] >= key:
            j = j-1
        L[i] = L[j]
        while i < j and L[i] <= key:
            i = i+1
        L[j] = L[i]
    L[i] = key
    print('排序中：',L)
    quickSort(L, low, i-1)
    quickSort(L, j+1, high)
    return L

num_list = [5, -4, 6, 3, 7, 11, 1, 2]
print('排序之前: ' + str(num_list))
print('排序之后: ' + str(quickSort(num_list,0,7)))

print('--------------使用Python内置函数----------------')
num_list = [5, -4, 6, 3, 7, 11, 1, 2]
print(sorted(num_list))

print('--------------习题1----------------')
print('利用Python内置的hex()函数，把一个整数转换成十六进制表示的字符串')
# a = input('请输入一个整数')
# print('输入的整数是：',a)
# print('转换为的十六进制数是：',hex(int(a)))

print('--------------习题2----------------')
print('请定义一个函数，quadartic(a,b,c),接受三个参数，返回一元二次方程ax2+bx+c=0的两个解')
def quadartic(a,b,c):
    return -c/(2*a+b)
print(quadartic(10,5,3))

x = lambda a,b,c:-c/(2*a+b)
print(x(10,5,3))


print('--------------习题3----------------')
# 给你一个包含不同英文字母和标点符号的文本，找到其中出现最多的字母，返回字母必须是字母的小写形式
# 检查字母时，不区分大小写。要确保不结算标点符号、数字和空格，只计算字母。
str = 'Apache Annotator is a collaborative community for creating annotation related ' \
      'code which works to provide a future for Annotator.js-based projects and plugins ' \
      'while enabling W3C spec-compliant Web Annotation in Web browsers, Web Publication readers,' \
      ' and the servers that serve them.'
def findWords(str):
    str1 = str.upper()
    # print(str1)
    list1 = list(str1)
    i = 0
    count = []
    L = len(list1)
    x2 = []
    while i < L:
        j = 0
        k = 0
        while j <L:
            if list1[i] == list1[j]:
                k +=1
            if j == L - 1:
                count.append(k)
                x2.append(list1[j])
            j += 1
        i += 1
    return(sorted(count,reverse=True)[0])
print('最多出现了%s次' % findWords(str))